package com.jahe.learn.nio;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 简单聊天功能的客户端
 * 启动两个进程，各自发送消息测试。
 * @author: jahe.lai
 * @create: 2019-12-25 15:12
 */
public class NioClient44 {

    public static void main(String[] args) throws Exception {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        socketChannel.connect(new InetSocketAddress("127.0.0.1", 8899));

        while (true) {
            selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            SelectionKey skey;
            for (Iterator<SelectionKey> it=selectionKeys.iterator(); it.hasNext();) {
                skey = it.next();
                if (skey.isConnectable()) {
                    SocketChannel client = (SocketChannel)skey.channel();

                    if (client.isConnectionPending()) {
                        client.finishConnect();

                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        buffer.put((LocalDateTime.now() + " 连接成功。。").getBytes());

                        buffer.flip();
                        client.write(buffer);

                        // 注册消息读取事件
                        client.register(selector, SelectionKey.OP_READ);

                        // 新开线程处理数据的输入，并写入到系统缓存 ，发送给服务器。
                        ExecutorService executorService = Executors.newSingleThreadExecutor();
                        executorService.submit(() -> {
                           while (true) {
                               try {
                                   buffer.clear();
                                   InputStreamReader streamReader = new InputStreamReader(System.in);
                                   BufferedReader bufferedReader = new BufferedReader(streamReader);
                                   String msg = bufferedReader.readLine();
                                   buffer.put(msg.getBytes());

                                   buffer.flip();
                                   client.write(buffer);
                               } catch (Exception ex) {
                                   ex.printStackTrace();
                               }
                           }
                        });
                    }
                } else if (skey.isReadable()) {
                    SocketChannel client = (SocketChannel)skey.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int len = client.read(buffer);
                    if (len > 0) {
                        String msg = new String(buffer.array());
                        System.out.println(msg);
                    }
                }
                it.remove();
            }
        }
    }
}
